
from flask import render_template, request, current_app, session, redirect \
                 , url_for
from functools import wraps
from werkzeug import check_password_hash
from wtforms import Form, TextField, PasswordField, HiddenField, validators

from photolog.database import dao
from photolog.photolog_logger import Log
from photolog.photolog_blueprint import photolog
from photolog.model.user import User


@photolog.teardown_request
def close_db_session(exception=None):

    try:
        dao.remove()
    except Exception as e:
        Log.error(str(e))


def login_required(f):

    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            session_key = \
                request.cookies.get(
                    current_app.config['SESSION_COOKIE_NAME'])

            is_login = False
            if session.sid == session_key and \
                session.__contains__('user_info') :
                is_login = True

            if not is_login:
                return redirect(url_for('.login_form',
                                        next=request.url))

            return f(*args, **kwargs)

        except Exception as e:
            Log.error("Photolog error occurs : %s" %
                      str(e))
            raise e

    return decorated_function


@photolog.route('/')
@login_required
def index():
    return redirect(url_for('.show_all'))


@photolog.route('/user/login')
def login_form():
    next_url = request.args.get('next', '')
    regist_username = request.args.get('regist_username', '')
    update_username = request.args.get('update_username', '')
    Log.info('(%s)next_url is %s' % (request.method, next_url))

    form = LoginForm(request.form)

    return render_template('login.html',
                           next_url=next_url,
                           form=form,
                           regist_username=regist_username,
                           update_username=update_username)


@photolog.route('/user/login', methods=['POST'])
def login():
    form = LoginForm(request.form)
    next_url = form.next_url.data
    login_error = None

    if form.validate():
        session.permanent = True

        username = form.username.data
        password = form.password.data
        next_url = form.next_url.data

        Log.info('(%s)next_url is %s' % (request.method, next_url))

        try:
            user = dao.query(User). \
                filter_by(username=username). \
                first()

        except Exception as e:
            Log.error(str(e))
            raise e

        if user:
            if not check_password_hash(user.password, password):
                login_error = 'Invalid password'

            else:
                session['user_info'] = user

                if next_url != '':
                    return redirect(next_url)
                else:
                    return redirect(url_for('.index'))
        else:
            login_error = 'User does not exist!'

    return render_template('login.html',
                   next_url=next_url,
                   error=login_error,
                   form=form)


@photolog.route('/logout')
@login_required
def logout():

    session.clear()

    return redirect(url_for('.index'))


class LoginForm(Form):

    username = \
        TextField('Username',
                  [validators.Required('insert'),
                   validators.Length(
                    min=4,
                    max=50,
                    message='4~ 50.')])

    password = PasswordField('New Password',
                [validators.Required('password.'),
                 validators.Length(
                    min=4,
                    max=50,
                    message='4~ 50.')])

    next_url = HiddenField('Next URL')

